#include "thread_pool.h"
int create_thread_runner(struct thread *t)
{
    pid_t id;
    if ((id = fork()) == 0)
    {
        close(t->pipe_w);
        for (;;)
        {
            task tsk;
            void *p_tsk = &tsk;
            if (__read_all(t->pipe_r, p_tsk, sizeof(tsk)) <= 0)
            {
                ERROR_PRINT("thread_pool read task err %d %s", errno, strerror(errno));
                exit(errno);
            }
            if (tsk == NULL)
            {
                INFO_PRINT("thread_pool exit success");
                exit(0);
            }
            uint16_t chk_sum = 0;
            if ((__read_all(t->pipe_r, &chk_sum, sizeof(uint16_t))) <= 0)
            {
                ERROR_PRINT("thread_pool read checksum err %d %s", errno, strerror(errno));
                exit(errno);
            }
            INFO_PRINT("thread_pool read task %p sizeof %ld", tsk, sizeof(tsk));
            INFO_PRINT("thread_pool read checksum %u", chk_sum);
            if (__verify_checksum(tsk, chk_sum) == 0)
            {

                tsk();
            }
            else
            {
                ERROR_PRINT("thread_pool error checksum exit");
                exit(1);
            }
            sleep(1);
        }
    }

    else
    {
        if (id < 0)
        {
            /* code */
            return -1;
        }

        t->id = id;
        return 0;
    }
}

int add_task_into_thread_pool(struct thread *t, task tsk)
{
    int err = -1;
    size_t tsk_buf = (size_t)tsk;
    void *p_task_buf = &tsk_buf;
    if ((__write_all(t->pipe_w, p_task_buf, sizeof(size_t)) <= 0))
    {
        ERROR_PRINT("add_task_into_thread_pool task %d %s", errno, strerror(errno));
        return err;
    };
    uint16_t chk_sum = __checksum(tsk);
    if ((__write_all(t->pipe_w, &chk_sum, sizeof(uint16_t))) <= 0)
    {
        ERROR_PRINT("add_task_into_thread_pool checksum %d %s", errno, strerror(errno));
        return err;
    };
    return 0;
}

int stop_thread_pool(struct thread *t)
{
    int err = -1;
    unsigned char close_command[sizeof(task)] = {0};
    if (__write_all(t->pipe_w, close_command, sizeof(task)) <= 0)
    {
        ERROR_PRINT("stop_thread_pool %d %s", errno, strerror(errno));
        return err;
    };

    while (close(t->pipe_w))
        ;
    waitpid(t->id, NULL, WUNTRACED);
    INFO_PRINT("stop_thread_pool success");
    return 0;
}

// 分配堆内存 需要free
struct thread *new_thread()
{
    struct thread *p_thread = malloc(sizeof(struct thread));
    int pi[2];
    pipe(pi);
    p_thread->pipe_r = pi[0];
    p_thread->pipe_w = pi[1];
    return p_thread;
}